/*
 * SimpleTUIOEventHandler.cpp
 *
 *  Created on: Aug 19, 2010
 *      Author: Ry
 */

#include <gl/glew.h>
#include <iostream>
#include "SimpleTUIOEventHandler.h"

using namespace std;

SimpleTUIOEventHandler::SimpleTUIOEventHandler(GUI *gui, GameWindow *window,
		ShaderProgram *shaderProgram, std::vector<Cursor*> *cursors,
		Object *player, SimpleWorld *world, vector<Mesh*> buildingMeshes) {
	this->gui = gui;
	this->window = window;
	this->shaderProgram = shaderProgram;
	this->cursors = cursors;

	this->player = player;
	this->building = world->newObject(buildingMeshes[0]);
	this->world = world;
	this->buildingMeshes = buildingMeshes;

	motionController = new BuilderMotionController(player);
	motionController->setMaxVelocity(20);

	ground.n = Vector3(0, 1, 0);
	ground.p = Vector3(0, 0, 0);
}

void SimpleTUIOEventHandler::handleEvent(float dts) {

	if (event.type == TUIOEvent::TUIO_ADD_CURSOR) {
		WindowResolution res = window->getCurrentResolution();
		Cursor *cursor = (Cursor*)gui->add(new Cursor(event.cursorId, shaderProgram));
		cursor->centerAt((int)(res.width * event.x), (int)(res.height * (1 - event.y)));
		cursors->push_back(cursor);
	}
	else if (event.type == TUIOEvent::TUIO_UPDATE_CURSOR) {

		WindowResolution res = window->getCurrentResolution();
		int x = (int)(res.width * event.x);
		int y = (int)(res.height * (1 - event.y));

		vector<Cursor*>::iterator i;
		for (i = cursors->begin(); i < cursors->end(); i++) {
			if ((*i)->getId() == event.cursorId) {
				(*i)->centerAt(x, y);
				break;
			}
		}

		GLdouble winX = x;
		GLdouble winY = y;
		GLdouble winZ = 0.0;

	 	GLdouble objX = 0.0;
	 	GLdouble objY = 0.0;
	 	GLdouble objZ = 0.0;

	 	GLdouble modelview[16];
	 	GLdouble projection[16];

	 	GLint viewport[4];

		world->getCamera()->view();

		glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
	 	glGetDoublev(GL_PROJECTION_MATRIX, projection);
	 	glGetIntegerv(GL_VIEWPORT, viewport);
	 	gluUnProject(winX, winY, winZ, modelview, projection, viewport, &objX, &objY, &objZ);

		Ray r;
		r.p = player->getPosition();
		Vector3 v = Vector3(objX, objY, objZ);
		r.d = v - r.p;

		Vector3 vec;
		if (ground.intersection(r, true, vec)) {
			buildPosition = Vector3(floor(vec.x), 0, floor(vec.z));
			building->positionAt(buildPosition);
		}

	}
	else if (event.type == TUIOEvent::TUIO_REMOVE_CURSOR) {
		vector<Cursor*>::iterator i;
		for (i = cursors->begin(); i < cursors->end(); i++) {
			if ((*i)->getId() == event.cursorId) {
				break;
			}
		}
		gui->destroy(*i);
		cursors->erase(i);
	}
}

SimpleTUIOEventHandler::~SimpleTUIOEventHandler() {
	delete motionController;
}
